<?php
/**
 * Created by PhpStorm.
 * User: liuhong
 * Date: 2019-05-08
 * Time: 17:15
 */

namespace app\service;


use think\Db;
use think\Exception;

class ThirdcainiaoService extends BaseService
{
    public $url;
    public $expressComModel;
    public $orderPrintModel;
    protected $orderInfo;
    public static $cpCode;
    public $cainiao_app_key='901248';
    protected static $cainiao_secretKey='Ox951R6kemQE0Z2qLzO9rc6dVf5836a3';//;'F53eqq903jQySV100Z8w06f9g914A13Z'
    public static $app_token='';//'CP553273';

    public function __construct()
    {
        $this->orderPrintModel=Db::name('orderprint');//Db::name('');
        $this->expressComModel=Db::name('expresscom');
        $this->app_token = config('cainiao_app_token');
        $this->orderInfo['express'] = config('cainiao_express_name');
        self::$cpCode = config('cainiao_express_id');
        //self::backCpCode($this->orderInfo['express']);
    }

    /**
     * 生成电子面单
     * @param $order_id
     * @param bool $status
     * @return array
     */
    public function buildOrder($order_id,$status=false){
        try{
            $this->orderInfo=OrderService::S()->findOrder(array('id'=>$order_id));
            if($this->orderInfo['checked']!=1){//已发货，不能继续发货
                LogService::S()->writeLog('ThirdService','订单状态不正确',$order_id);
                return array('code'=>202,'msg'=>'订单状态不能打印');
            }

            //$address=unserialize($this->orderInfo['delivery']);
            $goods=json_decode($this->orderInfo['goods_list'],true);//unserialize($this->orderInfo['goods']);
            $sender=array(
                'mobile' => config('cainiao_send_mobile'),
                'name'=> config('cainiao_send_name'),
                'phone'=> config('cainiao_send_phone'),
                'address'=>array(
                    'province'=> config('cainiao_send_province'),//$address['province'],
                    'city'=> config('cainiao_send_city'),//$address['county'],
                    'district'=> config('cainiao_send_district'),//$address['address'],
                    'detail'=> config('cainiao_send_detail'),//$address['address']
                )
            );
            //dump($this->orderInfo);die;
            //echo json_encode($sender);die;/*'phone'=>'057123222',*/
            //收件人信息
            $recipient=array(
                'name'=>$this->orderInfo['delivery_name'],
                'mobile'=>$this->orderInfo['delivery_mobile'],
                'address'=>array(
                    'province'=>$this->orderInfo['delivery_province'],
                    'town'=>$this->orderInfo['delivery_county'],
                    'city'=>$this->orderInfo['delivery_city'],
                    'district'=>$this->orderInfo['delivery_county'],
                    'detail'=>$this->orderInfo['delivery_address']
                )
            );
            $items=array();
            foreach ($goods as $k=>$v){
                $items[]=array(
                    'count'=>$v['goods_num'],
                    'name'=>$v['name']
                );
            }
            $array[]=array(
                'objectId'=>1,
                'orderInfo'=>array('orderChannelsType'=>'OTHERS','tradeOrderList'=>array($this->orderInfo['order_sn'])),//订单渠道平台
                'recipient'=>$recipient,
                'packageInfo'=>array(
                    'items'=>$items
                ),
                'templateUrl'=>self::backTempUrl(self::$cpCode),
                'userId'=>100
            );
            $data['cpCode']=self::$cpCode;
            $data['sender']=$sender;
            $data['tradeOrderInfoDtos']=$array;//array();
            $type='TMS_WAYBILL_GET';
            $re=self::httpPost($data,$type);//self::httpBase($data,$msg_type);
            //LogService::S()->writeLog('CainiaoService','backInfo',$re);
            if($re['success']=='true'){
                //保存该订单的电子面单号
                //$save['waybill_code']=$re['waybillCloudPrintResponseList'][0]['waybillCode'];
                $save['checked']=5;//待发货状态
                $save['express_no']=$re['waybillCloudPrintResponseList'][0]['waybillCode'];;//$save['waybill_code'];//待发货状态
                $save['express_com']=self::backExpress(self::$cpCode);//$save['waybill_code'];//待发货状态
                $save['send_time']=date('Y-m-d H:i:s');
                $save['print_num']+=$this->orderInfo['print_num']+1;
                $save['is_waybill']=1;//电子面单发货
                LogService::S()->writeLog('save','save',$save);
                $sre=OrderService::S()->saveOrder($save,array('id'=>$this->orderInfo['id']));
                if($sre===false){
                    LogService::S()->writeLog('ThirdService','buildOrder-save-error',$re);
                    return array('code'=>202,'msg'=>'保存电子面单号失败');
                }else{
                    $printData['order_id']=$this->orderInfo['id'];
                    $printData['create_time']=date('Y-m-d H:i:s');
                    $printData['waybill_code']=$save['express_no'];
                    $printData['print_data']=$re['waybillCloudPrintResponseList'][0]['printData'];
                    $printData['status']=1;
                    $print_re_where=array('order_id'=>$printData['order_id']);
                    if($status){
                        $this->orderPrintModel->where($print_re_where)->update($printData);
                    }else{
                        $this->orderPrintModel->insert($printData);
                    }
                    return array('code'=>200,'msg'=>'发送成功','data'=>$re['waybillCloudPrintResponseList'][0]['printData'],'waybill_code'=>$re['waybillCloudPrintResponseList'][0]['waybillCode']);
                }
            }else{
                LogService::S()->writeLog('ThirdService','buildOrder-error',$re);
                return array('code'=>202,'msg'=>'获取电子面单号失败','data'=>$re);
            }
        }catch (Exception $ex){
            echo $ex->getMessage();die;
            return array();
        }

        //dump(json_encode($data));die;
    }

    public function xmlToArray($xml)
    {
        //将XML转为array
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }

    /**
     * 更新电子面单
     */
    public function updOrder(){
        $goods=unserialize($this->orderInfo['goods']);
        $address=unserialize($this->orderInfo['delivery']);
        $sender=array(
            'mobile'=>'15523375429',
            'name'=>'刘洪',
            'phone'=>'15523375429',
            'address'=>'刘洪测试的'
        );
        //收件人信息
        $recipient=array(
            'name'=>$address['delivery_name'],
            'mobile'=>$address['delivery_mobile'],
            'address'=>array(
                'province'=>$address['province'],
                'town'=>$address['county'],
                'city'=>$address['city'],
                'district'=>$address['address'],
                'detail'=>$address['address']
            )
        );
        $items=array();
        foreach ($goods as $k=>$v){
            $items[]=array(
                'count'=>$v['num'],
                'name'=>$v['goods_name']
            );
        }
        $array=array(
            'objectId'=>1,
            'orderInfo'=>array('orderChannelsType'=>'OTHERS','tradeOrderList'=>array($this->orderInfo['order_sn'])),//订单渠道平台
            'recipient'=>$recipient,
            'packageInfo'=>array(
                'items'=>$items
            ),
            'templateUrl'=>'',
            'userId'=>100
        );
        $data['cpCode']=$this->cpCode;
        $data['sender']=$sender;
        $data['tradeOrderInfoDtos']=$array;//array();
        $result=self::httpBase($data,array());
        $result=json_decode($result,true);
        if($result['success']=='true'){
            return array('code'=>200,'msg'=>'更新成功');
        }else{
            return array('code'=>202,'msg'=>'更新电子面单号失败');
        }
    }


    //获取发货地
    public function queryWayBiLi(){
        $this->url='https://linkdaily.tbsandbox.com/gateway/link.do';
        $data['cpCode']=self::$cpCode;//物流公司code
        $re=self::httpBase($data);
        $re=json_decode($re,true);
        return $re;
    }

    //取消电子面单接口
    public function discard($order_id){
        $this->orderInfo=OrderService::S()->findOrder(array('id'=>$order_id));
        $this->url='https://linkdaily.tbsandbox.com/gateway/link.do';//'http://link.cainiao.com/gateway/link.do';
        $data['cpCode']=self::$cpCode;
        $data['waybillCode']=$this->orderInfo['express_no'];//'803566739495200291';//$this->orderInfo['waybill_code'];
        $msg_type='TMS_WAYBILL_DISCARD';
        $re=self::httpPost($data,$msg_type);//self::httpBase($data,$msg_type);
        if($re['discardResult']=='true'){//是否已取消
            $save['status']=3;//订单取消
            $this->orderPrintModel->where(array('order_id'=>$this->orderInfo['id']))->update($save);
            if($this->orderInfo['checked']==4 || $this->orderInfo['checked']==3){
                $saveOrder['checked']=$this->orderInfo['checked'];
            }else{
                $saveOrder['checked']=1;
            }
            OrderService::S()->saveOrder($saveOrder,array('id'=>$this->orderInfo['id']));//$this->ord->where(array('order_id'=>$this->orderInfo['order_id']))->save($save);
            return array('code'=>200,'msg'=>'取消成功');
            // OrderService::S()->saveOrder($this->orderInfo['order_id']);
        }else{
            return array('code'=>202,'取消失败');
        }
    }


    public function queryGuanxi(){
        $msg_type='TMS_WAYBILL_SUBSCRIPTION_QUERY';
        $data=array(
            'cpCode'=>'YTO'
        );
        $re=self::httpPost($data,$msg_type);//self::httpBase($data,$msg_type);
        dump($re);die;
    }

    //返回模版
    public function backTempUrl($cp_code){
        $array=array(
            'YTO'=>'http://cloudprint.cainiao.com/template/standard/201/160',
        );
        if(!$array[$cp_code]){
            return 'http://cloudprint.cainiao.com/template/standard/201/160';
        }else{
            return $array[$cp_code];
        }

    }
    /*
     * @param $content
     * @return mixed
     */
    public function httpBase($content,$msg_type){
        //echo json_encode($array);die;
        $content=json_encode($content,JSON_UNESCAPED_UNICODE);
        $data['msg_type']=$msg_type;//'TMS_WAYBILL_GET';
        $data['logistic_provider_id']=self::$app_token;
        $data['data_digest']=base64_encode(md5($content.self::$cainiao_secretKey,true));
        $data['logistics_interface']=$content;//请求报文
        dump($data);die;
        $re=CurlService::S()->httpMethodPostApplication($this->url,$data);
        return $re;
    }

    /**
     * @param $exp_name
     * @return mixedz
     */
    public function backCpCode($exp_name){
        $where=array('ecom_name'=>$exp_name);
        $filed='cpcode,template_url';
        return $this->expressComModel->field($filed)->where($where)->find();
    }

    public function backExpress($exp_code){
        $where=array('cpcode'=>$exp_code);
        return $this->expressComModel->where($where)->value('name');
    }

    public function httpPost($apiContentArr,$mgsType)
    {
        //测试地址
        //$dailyUrl = 'http://linkdaily.tbsandbox.com/gateway/link.do';
        //正式地址  测试需要使用正式地址
        $dailyUrl = 'http://link.cainiao.com/gateway/link.do';
        $apiContentStr = json_encode($apiContentArr);
        $post = array(
            'msg_type' => $mgsType,//'TMS_WAYBILL_GET',
            'logistic_provider_id' => self::$app_token,//self::SHANGJIA_TOKEN,
            'logistics_interface' => $apiContentStr,
            'data_digest' => $this->__dataDigest($apiContentStr, self::$cainiao_secretKey),
        );
        //dump($post);die;
        //$this->__logs("[cainiao:test:post] post: " . json_encode($post));
        $curlResult = $this->request($dailyUrl, $post);
        return $curlResult;
    }

    //public function __postParamCurl($url, $option, $header = array(), $type = 'POST')
    public static function request($url, $post, $header = array(), $type = 'POST')
    {
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在

        // 模拟用户使用的浏览器
        //curl_setopt ( $curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)' );

        $params = http_build_query($post);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $params);     // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);             // 设置超时限制防止死循环
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);     // 设置HTTP头
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);       // 获取的信息以文件流的形式返回
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $type);
        $result = curl_exec($curl);
        $errno = curl_errno($curl);
        $error = curl_error($curl);
        curl_close($curl); // 关闭CURL会话
        $result=json_decode($result,true);
        if (!empty($errno) || !empty($error)) {
            //print_r( "[cainiao:request:end] curl faild end. error! errno:{$errno}, error:{$error}. " );
            //self::__logs("[cainiao:request:end] curl faild end. error! errno:" . $errno . ", error:" . $error);
            LogService::S()->writeLog('CainiaoService','request',$result);
            return array();
        } else {
            LogService::S()->writeLog('CainiaoService','request',$result);
            return $result;
        }
        //return $result;
    }

    public function __dataDigest($content, $keys)
    {
        $str = $content . $keys;
        return base64_encode(pack('H*', md5($str)));
    }

    public function caiNiaoinfo(){
        $array=array(
            'ZJS'=>'http://cloudprint.cainiao.com/template/standard/901/110',
            'YUNDA'=>'http://cloudprint.cainiao.com/template/standard/401/152',
        );
    }
}